/*!
 * Gensee EasyCast JavaScript SDK
 * http://www.gensee.com/
 *
 * Date: 2013-1-29
 */
(function( window, undefined ) {
	
	/*
	 * ===========the first===============
	 */
	//防止如JSP页面include、HTML碎片加载等引起的多次装载
	if(loaded())return;
	
	//FIXME:Config
	var Config={
		server:{
			baseURL:"svr",
			videoURL:"/video_{roomid}.js",
			docURL:"/doc_{roomid}.js",
			qaURL:"/qa_{roomid}.js",
			rollcallURL:"/site/module/rollcall/{roomid}_{authcode}",
			clientLaunchURL:"/site/module/clientlaunch/{roomid}_{authcode}",
			clientDownloadURL:"/site/module/clientdownload/{roomid}_{authcode}"
		},
		//第一个必须是视频标签
		tags:["vd","doc","qa","rollcall","client-launch","client-download","vote"],
		tagAttrs:{"vd":["roomid","uname","authcode"],
			"doc":["roomid","uname","authcode"],
			"qa":["roomid","uname","authcode"],
			"rollcall":[],
			"client-launch":["roomid","uname","authcode"],
			"client-download":[],
			"vote":[]}
	};
	
	/*
	 * ===========正文===============
	 */
	var
	//SDK
	SDK = (function() {
		var that = {};
		that.defaultKey = "GsEc_SDK_default_key_"+(new Date()).getTime();
		var logs = []; 
		that.suites={}; 
		that.IE = /msie/i.test(navigator.userAgent);
		that.baseURL=(function(){
			var scripts = document.getElementsByTagName("script");
			for(var i=0;i<scripts.length;i++){
				var script = scripts[i];
				var idx = script.src.indexOf("sdk/js/ec.js");
				if (idx > 0) {
					return script.src.substring(0, idx-1);
				}
			}
		})();
		that.register=function(ns, maker) {
			var NSList = ns.split(".");
			var step = that;
			var k = null;
			while (k = NSList.shift()) {
				if (NSList.length) {
					if (step[k] === undefined) {
						step[k] = {};
					}
					step = step[k];
				} else {
					if (step[k] === undefined) {
						step[k] = maker(that);
					}
				}
			}
		};
		that.loadScript=function(sURL, callBack) {
			var js = document.createElement("script");
			js.charset = "UTF-8";
			js.src = sURL;
			if(callBack){
				if (IE) {
					js.onreadystatechange = function() {
						if (js.readyState.toLowerCase() == "complete"
							|| js.readyState.toLowerCase() == "loaded") {
							callBack.call(callBack);
						}
					};
				} else {
					js.onload = function() {
						callBack.call(callBack);
					};
				}
			}
			document.getElementsByTagName("head")[0].appendChild(js);
		};
		that.trim = function(str) {
			if (typeof str !== "string") {
				return str;
			}
			if (typeof str.trim === "function") {
				return str.trim();
			} else {
				return str.replace(/^(\u3000|\s|\t|\u00A0)*|(\u3000|\s|\t|\u00A0)*$/g, "");
			}
		};
		that.isEmpty = function(obj){
			if(obj === undefined){
				return true;
			}else if(obj==null){
				return true;
			}else if(typeof obj === "string"){
				if(that.trim(obj) == ""){
					return true;
				}
			}
			return false;
		};
		that.isNotEmpty=function(obj){
			return !that.isEmpty(obj);
		};
		that.elem = function(id) {
			if (typeof id === "string") {
				return document.getElementById(id);
			} else {
				return id;
			}
		};
		that.Event=(function(type, target, data){
			this.type=type;
			this.target = target;
			this.data = data;
		});
		
		that.log = function(str) {
			logs.push("[" +(new Date()).toLocaleTimeString()+ "]: "+ str+"");
		};
		that.logs = function(n) {
			return logs;
		};
		that.outputlogs=function(n){
			return logs.splice(0, n || logs.length);
		};
		
		that.JSONP = (function( window, undefined ) {
			var grobalName="__GsEcJsonp";
			var jsonp = window[grobalName] = window[grobalName]||{}, N=0;
			jsonp.send = function(url, callbackname) {
				var s = "?";
				if(url.indexOf("?")>0){
					s = "&";
				}
			    var _url = url + s +"jsonpcallback="+callbackname;
			    that.loadScript(_url);
			};
			jsonp.createJsonpCallback = function(callbackFn){
				var callback = "jsonpcallback_"+N;
				N++;
				jsonp[callback] = function(data){
					delete jsonp[callback];
					return callbackFn(data);
				};
				return grobalName+"."+callback;
			};
			jsonp.process = function(url, success){
				jsonp.send(url, jsonp.createJsonpCallback(success));
			};
			return jsonp;
		})(window);
		
		//套件
		var Suite = (function(){
			var S = function(key){
				if(that.isEmpty(key)){
					key = that.defaultKey;
				}
				this.key = key;
				this.init();
			};
			
			S.fn = S.prototype = {
				constructor: S,
				init: function(){
					this.eventsmap = {};
					this.widgets = [];
					this.depositCenter = {
						demands:{},
						deposits:{},
						demand:function(id, takeoutFn){
							if(typeof takeoutFn !== "function"){
								that.log("[SDK]WARN! the second arg of demand() must be a function - "+takeoutFn);
							}
							if(this.deposits[id]===undefined){
								this.demands[id]=takeoutFn;
							}else{
								try{
									takeoutFn(this.deposits[id]);
								}catch(e){}
								delete this.deposits[id];
							}
						},
						deposit:function(id, anything){
							if(this.demands[id]===undefined){
								this.deposits[id]=anything;
							}else{
								try{
									this.demands[id](anything);
								}catch(e){}
								delete this.demands[id];
							}
						}
					};
				},
				shakehand:function(wg1, wg2){
					wg1.know(wg2.data, wg2.type);
					wg2.know(wg1.data, wg1.type);
				},
				load:function(widget){
					if(this.masterWidget===undefined){
						this.masterWidget=widget;
					}else{
						this.shakehand(widget, this.masterWidget);
					}
					widget.suite = this;
					this.widgets.push(widget);
				},
				bind:function(type, handler){
					if(!this.eventsmap[type]){
						this.eventsmap[type] = [];
					}
					this.eventsmap[type].push(handler);
				},
				unbind:function(type, handler){
					if(this.eventsmap[type]){
						for(var i in this.eventsmap[type]){
							if(this.eventsmap[type][i]==handler){
								delete this.eventsmap[type][i];
								break;
							};
						}
					}
				},
				fire:function(event){
					if(!(event instanceof that.Event)){
						that.log("[SDK]ERROR! It's not instanceof Event - "+event);
						throw "[SDK]ERROR! It's not instanceof Event - "+event;
					}
					var handlers = this.eventsmap[event.type];
					if(handlers){
						for(var i in handlers){
							handlers[i](event.data);
						}
					}else{
						var pre = this.key==that.defaultKey?"":this.key+".";
						that.log("[SDK]WARN! No event handler for \""+pre+event.type+"\"");
					}
				}
			};
			return S;
		})();

		that.suite=function(key){
			if(that.isEmpty(key)){
				key = that.defaultKey;
			}
			var suite = that.suites[key];
			if(typeof suite == "undefined"){
				suite = new Suite(key);
				that.suites[key] = suite;
			}
			return suite;
		};
		
		that.isKeyValid=function(key){
			if(that.isEmpty(key)){
				key = that.defaultKey;
			}
			if(suites[key] === undefined){
				return false;
			}
			return true;
		};
		
		//部件
		var Widget = (function(){
			var W = function(type, knowFn, data){
				this.type = type;
				this.know = function(data){
					setTimeout(function(){knowFn(data);},0);
				};
				this.data = data;
			};
			
			W.fn = W.prototype = {
				constructor: W,
				init: function(){
				}
			};
			return W;
		})();
		
		that.createWidget = function(type, shakehandFn, data){
			return new Widget(type, shakehandFn, data);
		};
		
		return that;
	})();
	
	//core.dom
	SDK.register("core.dom.addEvent", function(K){
		return function(sNode, sEventType, oFunc) {
			var oElement = K.elem(sNode);
			if (oElement == null) {
				return
			}
			sEventType = sEventType || "click";
			if ((typeof oFunc).toLowerCase() != "function") {
				return
			}
			if (oElement.attachEvent) {
				oElement.attachEvent("on" + sEventType, oFunc);
			} else {
				if (oElement.addEventListener) {
					oElement.addEventListener(sEventType, oFunc, false);
				} else {
					oElement["on" + sEventType] = oFunc;
				}
			}
		};
	});
	SDK.register("core.dom.ready", function(K){
		var funcList = [];
		var inited = false;
		var addEvent = K.core.dom.addEvent;
		var isDomComplete = function() {
			if (!inited) {
				if (document.readyState === "complete") {
					return true;
				}
			}
			return inited;
		};
		var exec_func_list = function() {
			if (inited == true) return;
			inited = true;
			for ( var i = 0 ; i < funcList.length; i++) {
				if (typeof funcList[i] == "function") {
					try {
						funcList[i].call();
					} catch (e) {
						K.log(e);
					}
				}
			}
			funcList = [];
		};
		var IEContentLoaded = function() {
			if (isDomComplete()) {
				exec_func_list();
				return
			}
			try {
				document.documentElement.doScroll("left");
			} catch (e) {
				setTimeout(arguments.callee, 50);
				return;
			}
			exec_func_list();
		};
		var timingCheck = function() {
			if (isDomComplete()) {
				exec_func_list();
				return;
			}
			setTimeout(arguments.callee, 50);
		};
		var bindDomLoad = function() {
			addEvent(document, "DOMContentLoaded", exec_func_list);
		};
		var bindWinLoad = function() {
			addEvent(window, "load", exec_func_list);
		};
		if (!isDomComplete()) {
			if (K.IE && window === window.top) {
				IEContentLoaded();
			}
			bindDomLoad();
			timingCheck();
			bindWinLoad();
		}
		return function(fn) {
			if (isDomComplete()) {
				if (typeof fn == "function") {
					fn.call();
				}
			} else {
				funcList.push(fn);
			}
		};
	
	});
	//core.util
	SDK.register("core.util.assignProperties", function() {
		return function(oSource, oProperties) {
			if (typeof oProperties != "undefined") {
				for (var key in oProperties) {
					oSource[key] = oProperties[key];
				}
			}
			return oSource;
		};
	});
	SDK.register("core.util.parseURL", function() {
		return function(url) {
			var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+\.[0-9A-Za-z]+)?(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
			var names = ["url","scheme","slash","host","port","path","query","hash"];
			var results = parse_url.exec(url);
			var parts = {};
			for ( var i = 0, len = names.length; i < len; i += 1) {
				parts[names[i]] = results[i] || "";
			}
			return parts;
		};
	});
	SDK.register("core.util.browser", function() {
		var J = navigator.userAgent.toLowerCase();
		var S = window.external || "";
		var L, M, N, T, O;
		var K = function(U) {
			var V = 0;
			return parseFloat(U.replace(/\./g, function() {
				return (V++ == 1) ? "" : ".";
			}));
		};
		try {
			if ((/windows|win32/i).test(J)) {
				O = "windows";
			} else {
				if ((/macintosh/i).test(J)) {
					O = "macintosh";
				} else {
					if ((/rhino/i).test(J)) {
						O = "rhino";
					}
				}
			}
			if ((M = J.match(/applewebkit\/([^\s]*)/)) && M[1]) {
				L = "webkit";
				T = K(M[1]);
			} else {
				if ((M = J.match(/presto\/([\d.]*)/)) && M[1]) {
					L = "presto";
					T = K(M[1]);
				} else {
					if (M = J.match(/msie\s([^;]*)/)) {
						L = "trident";
						T = 1;
						if ((M = J.match(/trident\/([\d.]*)/)) && M[1]) {
							T = K(M[1]);
						}
					} else {
						if (/gecko/.test(J)) {
							L = "gecko";
							T = 1;
							if ((M = J.match(/rv:([\d.]*)/)) && M[1]) {
								T = K(M[1]);
							}
						}
					}
				}
			}
			if (/world/.test(J)) {
				N = "world";
			} else {
				if (/360se/.test(J)) {
					N = "360";
				} else {
					if ((/maxthon/.test(J)) || typeof S.max_version == "number") {
						N = "maxthon";
					} else {
						if (/tencenttraveler\s([\d.]*)/.test(J)) {
							N = "tt";
						} else {
							if (/se\s([\d.]*)/.test(J)) {
								N = "sogou";
							}
						}
					}
				}
			}
		} catch (R) {
		}
		var Q = {
			OS : O,
			CORE : L,
			Version : T,
			EXTRA : (N ? N : false),
			IE : /msie/.test(J),
			OPERA : /opera/.test(J),
			MOZ : /gecko/.test(J) && !/(compatible|webkit)/.test(J),
			IE5 : /msie 5 /.test(J),
			IE55 : /msie 5.5/.test(J),
			IE6 : /msie 6/.test(J),
			IE7 : /msie 7/.test(J),
			IE8 : /msie 8/.test(J),
			IE9 : /msie 9/.test(J),
			SAFARI : !/chrome\/([\d.]*)/.test(J) && /\/([\d.]*) safari/.test(J),
			CHROME : /chrome\/([\d.]*)/.test(J),
			IPAD : /\(ipad/i.test(J),
			IPHONE : /\(iphone/i.test(J),
			ITOUCH : /\(itouch/i.test(J),
			MOBILE : /mobile/i.test(J)
		};
		return Q;
	});
	SDK.register("core.util.strToJson", function($) {
		var at, ch, escapee = {
			'"' : '"',
			"\\" : "\\",
			"/" : "/",
			b : "\b",
			f : "\f",
			n : "\n",
			r : "\r",
			t : "\t"
		}, text, error = function(m) {
			throw {
				name : "SyntaxError",
				message : m,
				at : at,
				text : text
			}
		}, next = function(c) {
			if (c && c !== ch) {
				error("Expected '" + c + "' instead of '" + ch + "'")
			}
			ch = text.charAt(at);
			at += 1;
			return ch
		}, number = function() {
			var number, string = "";
			if (ch === "-") {
				string = "-";
				next("-")
			}
			while (ch >= "0" && ch <= "9") {
				string += ch;
				next()
			}
			if (ch === ".") {
				string += ".";
				while (next() && ch >= "0" && ch <= "9") {
					string += ch
				}
			}
			if (ch === "e" || ch === "E") {
				string += ch;
				next();
				if (ch === "-" || ch === "+") {
					string += ch;
					next()
				}
				while (ch >= "0" && ch <= "9") {
					string += ch;
					next()
				}
			}
			number = +string;
			if (isNaN(number)) {
				error("Bad number")
			} else {
				return number
			}
		}, string = function() {
			var hex, i, string = "", uffff;
			if (ch === '"') {
				while (next()) {
					if (ch === '"') {
						next();
						return string
					} else {
						if (ch === "\\") {
							next();
							if (ch === "u") {
								uffff = 0;
								for (i = 0; i < 4; i += 1) {
									hex = parseInt(next(), 16);
									if (!isFinite(hex)) {
										break
									}
									uffff = uffff * 16 + hex
								}
								string += String.fromCharCode(uffff)
							} else {
								if (typeof escapee[ch] === "string") {
									string += escapee[ch]
								} else {
									break
								}
							}
						} else {
							string += ch
						}
					}
				}
			}
			error("Bad string")
		}, white = function() {
			while (ch && ch <= " ") {
				next()
			}
		}, word = function() {
			switch (ch) {
			case "t":
				next("t");
				next("r");
				next("u");
				next("e");
				return true;
			case "f":
				next("f");
				next("a");
				next("l");
				next("s");
				next("e");
				return false;
			case "n":
				next("n");
				next("u");
				next("l");
				next("l");
				return null
			}
			error("Unexpected '" + ch + "'")
		}, value, array = function() {
			var array = [];
			if (ch === "[") {
				next("[");
				white();
				if (ch === "]") {
					next("]");
					return array
				}
				while (ch) {
					array.push(value());
					white();
					if (ch === "]") {
						next("]");
						return array
					}
					next(",");
					white()
				}
			}
			error("Bad array")
		}, object = function() {
			var key, object = {};
			if (ch === "{") {
				next("{");
				white();
				if (ch === "}") {
					next("}");
					return object
				}
				while (ch) {
					key = string();
					white();
					next(":");
					if (Object.hasOwnProperty.call(object, key)) {
						error('Duplicate key "' + key + '"')
					}
					object[key] = value();
					white();
					if (ch === "}") {
						next("}");
						return object
					}
					next(",");
					white()
				}
			}
			error("Bad object")
		};
		value = function() {
			white();
			switch (ch) {
			case "{":
				return object();
			case "[":
				return array();
			case '"':
				return string();
			case "-":
				return number();
			default:
				return ch >= "0" && ch <= "9" ? number() : word()
			}
		};
		return function(source, reviver) {
			var result;
			text = source;
			at = 0;
			ch = " ";
			result = value();
			white();
			if (ch) {
				error("Syntax error")
			}
			return typeof reviver === "function" ? (function walk(holder, key) {
				var k, v, value = holder[key];
				if (value && typeof value === "object") {
					for (k in value) {
						if (Object.hasOwnProperty.call(value, k)) {
							v = walk(value, k);
							if (v !== undefined) {
								value[k] = v
							} else {
								delete value[k]
							}
						}
					}
				}
				return reviver.call(holder, key, value)
			}({
				"" : result
			}, "")) : result
		}
	});
			
			
	//GSML标签管理
	var GSML = (function(){
		var ML = {};
		ML.tags = [];
		ML.NS = "ec";
		var Tag = (function(){
			var T = function(tagElem, tagName){
				this.elem = tagElem;
				this.name = tagName;
				this.init();
			};
			T.fn = T.prototype = {
				constructor: T,
				init:function(){
					//check
					this.checkElem(this.elem);
					//build script url
					this.url = Config.server.baseURL;
					if(this.name=="vd"){
						this.url+=Config.server.videoURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else if(this.name=="doc"){
						this.url+=Config.server.docURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else if(this.name=="qa"){
						this.url+=Config.server.qaURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else if(this.name=="rollcall"){
						this.url+=Config.server.rollcallURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else if(this.name=="client-launch"){
						this.url+=Config.server.clientLaunchURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else if(this.name=="client-download"){
						this.url+=Config.server.clientDownloadURL.replace("{roomid}", this.attr("roomid"))
						.replace("{authcode}", this.attr("authcode"));
					}else{
						SDK.log("[SDK]ERROR! Tag name invalid - "+this.name);
					}
					this.url+="?uid="+this.attr("uid")+
						"&uname="+encodeURIComponent(this.attr("uname"))+
						"&group="+this.attr("group");
				},
				checkElem:function(tagElem){
					//TODO:
					
				},
				attr:function(name){
					var value = "";
					try{
						value = this.elem.getAttribute(name);
					}catch(e){
					}
					return SDK.isEmpty(value)?"":value;
				},
				loadWidget:function(){
					var that = this;
					that.elem.innerHTML = '<span style="background:url('+SDK.baseURL+'/sdk/images/loading1.gif) no-repeat;height:18px;padding:0 0 2px 20px;">Loading...</span>';
					SDK.JSONP.process(this.url, function(data){
						if(typeof data == "string" ){
							that.elem.innerHTML = data;
						}else if(typeof data == "object"){
							that.elem.innerHTML = "";
							that.elem.appendChild(data);
						}else if(typeof data == "function"){
							that.elem.innerHTML = "";
							data(that.elem);
						}else if(data == undefined){
							that.elem.innerHTML = "";
						}else{
							that.elem.innerHTML = "";
							SDK.log("[SDK]ERROR! Can't process JSONP-"+that.url +","+data);
						}
						return that.elem;
					});
				}
			};
			return T;
		})();
		
		var getElementsByTagName = function(tagName) {
			var browser= SDK.core.util.browser;
			var tagNameWithNamespace = ML.NS + ":"+ tagName;
			if (browser.IE) {
				try {
					var nsps = document.namespaces;
					if (nsps && nsps[ML.NS]) {
						return document.getElementsByTagName(tagName).length == 0 ? document
								.getElementsByTagName(tagNameWithNamespace)
								: document.getElementsByTagName(tagName);
					}
				} catch (e) {
				}
				return document.getElementsByTagName(tagNameWithNamespace);
			} else {
				if (browser.MOZ) {
					return document.getElementsByTagNameNS(document.body.namespaceURI, tagNameWithNamespace);
				} else {
					return document.getElementsByTagName(tagNameWithNamespace);
				}
			}
		};
		
		ML.loadTag=function(tagElem, tagName){
			var tag = new Tag(tagElem, tagName);
			tag.loadWidget();
			//TODO:对doc、qa、vote等进行分组名称检查，不存在相同分组的vd则添加log。
			ML.tags.push(tag);
		};
		
		ML.loadTags=function(){
			var tagNames = Config.tags;
			for (var i=0; i<tagNames.length; i++) {
				var tagName = tagNames[i];
				var tagElems = getElementsByTagName(tagName);
				for(var j=0;j<tagElems.length;j++){
					var tagElem = tagElems[j];
					ML.loadTag(tagElem, tagName);
				}
			}
		};
		(function() {
			try {
				if (document.namespaces && !document.namespaces.item[ML.NS]) {
					document.namespaces.add(ML.NS);
				}
			} catch (e) {
			}
		})();	
		return ML;
	})();
	
	//CMD
	var cmdManager=(function(){
		var D = {};
		D.cmdMap={};
		D.type=function(option){
			if(typeof option ==="string"){
				return D.cmdMap[option]?D.cmdMap[option]:option;
			}else{
				SDK.core.util.assignProperties(D.cmdMap, option);
			}
		};
		return D;
	})();
	
	//API
	SDK.register("api.bind", function(){
		return function(type, handler, key){
			var suite = SDK.suite(key);
			suite.bind(type, handler);
		};
	});
	SDK.register("api.fire", function(){
		return function(type, data, key){
			var suite = SDK.suite(key);
			suite.fire(type, data);
		};
	});
	SDK.register("api.ready", function(){
		return function(callback){
			SDK.core.dom.ready(callback);
		};
	});
	SDK.register("api.widget.complete", function(){
		return function(type, shakehandFn, data, key){
			var suite = SDK.suite(key);
			var wg = SDK.createWidget(type, shakehandFn, data);
			suite.load(wg);
		};
	});
	
	/*
	 * ===========ready===============
	 */
	//装载定制标签
	SDK.api.ready(GSML.loadTags);
	
	/*
	 * ===========open API===============
	 */
	//SDK开发者接口
	var GsEc = window.GsEc = {
		room:(function(){
			var Room = function(key){
				this.key = key;
				this.suite = SDK.suite(key);
				this.bind=function(type, handler){
					this.suite.bind(type, handler);
				};
				this.unbind=function(type, handler){
					this.suite.unbind(type, handler);
				};
				this.command=function(cmd, data){
					var type = cmdManager.type(cmd);
					var event = new SDK.Event(type, this, data);
					this.suite.fire(event);
				};
				//索取
				this.demand=function(id, takeoutFn){
					this.suite.depositCenter.demand(id, takeoutFn);
				};

			};
			return function(key){
				return new Room(key);
			};
		})(),
		loadTag:function(tagElem, tagName){
			GSML.loadTag(tagElem, tagName);
		},
		monitor:{
			logs:function(){
				return SDK.logs();
			},
			events:function(){
				var types = [];
				for(var i in SDK.suites){
					var suite = SDK.suites[i];
					for(var type in suite.eventsmap){
						var pre = "";
						if(suite.key != SDK.defaultKey){
							pre = suite.key+".";
						}
						types.push(pre+type);
					};
				}
				return types;
			},
			commandMap:function(){
				return cmdManager.cmdMap;
			}
		}
	};
	
	//内部模块调用接口
	GsEc._inner_ = {
		widget:{
			complete:function(type, shakehandFn, data, key){
				SDK.api.widget.complete(type, shakehandFn, data, key);
			}
		},
		bind:function(type, handler, key){
			var suite = SDK.suite(key);
			suite.bind(type, handler);
		},
		unbind:function(type, handler, key){
			var suite = SDK.suite(key);
			suite.unbind(type, handler);
		},
		command:function(cmd, data, key){
			var type = cmdManager.type(cmd);
			var suite = SDK.suite(key);
			var event = new SDK.Event(type, this, data);
			suite.fire(event);
		},
		commandMap:function(option){
			cmdManager.type(option);
		},
		//寄放
		deposit:function(id, data, key){
			var suite = SDK.suite(key);
			suite.depositCenter.deposit(id, anything);
		},
		//索取
		demand:function(id, takeoutFn){
			this.suite.depositCenter.demand(id, takeoutFn);
		},
		strToJson:function(str){
			return SDK.core.util.strToJson(str);
		}
		
	};
	
	/*
	 * ===========the last===============
	 */
	function loaded(){
		return window.GsEc !== undefined;
	}
	GsEc.option=function(options){
		if(SDK.isNotEmpty(options.log)){
			if(typeof options.log != "function"){
				that.log("[SDK]ERROR! GsEc.option(options):options.log not a function -"+(typeof options.log));
				return;
			}
			SDK.log = options.log;
		}
	};
	(function(){
		var sources = {
			html5 : {
//				js : [SDK.baseURL+"/sdk/js/html5.js?version=20130219"]
			},
			flash : {
//				js : [SDK.baseURL+"/sdk/js/flash.js?version=20130219"]
			}
		};
		for(var key in sources){
			var source = sources[key];
			if(source.js){
				for(var i in source.js){
					SDK.loadScript(source.js[i]);
				}
			}
		}
	})();
	
})( window );


